{
    let app = new Vue({
        el: '.stage',
        data: {
            coords: {
                x: 0,
                y: 0,
            },
            size: {
                width: 4,
                height: 4
            },
            obstacles: [{
                x: 2,
                y: 1
            },{
                x: 1,
                y: 2
            }],
            targets: [{
                x: 2,
                y: 2
            }],
            direction: "right",
            showTip_: false,
            tipText_: ""
        },
        methods: {
            showTip: function (text) {
                this.showTip_ = true;
                this.tipText_ = text;
            },
            hideTip: function () {
                this.showTip_ = false;
            }
        }
    });

    class Env {
        constructor (o) {
            this._o = o;
            this.vueRoot = app;
            if ( o && o.size ) {
                this.vueRoot.size = o.size;
            }
        }

        _go(action) {
            switch (action) {
                case "left":
                    this.vueRoot.direction = "left";
                    if ( this.vueRoot.coords.x > 0 ) {
                        this.vueRoot.coords.x--;
                    }
                    break;
                case "right":
                    this.vueRoot.direction = "right";
                    if ( this.vueRoot.coords.x < (this.vueRoot.size.width - 1)) {
                        this.vueRoot.coords.x++;
                    }
                    break;
                case "up":
                    this.vueRoot.direction = "up";
                    if ( this.vueRoot.coords.y > 0 ) {
                        this.vueRoot.coords.y--;
                    }
                    break;
                case "down":
                    this.vueRoot.direction = "down";
                    if ( this.vueRoot.coords.y < (this.vueRoot.size.height - 1) ) {
                        this.vueRoot.coords.y++;
                    }
                    break;
                default:
                    break;
            }
            return {
                x: this.vueRoot.coords.x,
                y: this.vueRoot.coords.y
            }
        }

        reset(callback) {
            this.vueRoot.coords.x = 0;
            this.vueRoot.coords.y = 0;
            this.vueRoot.size.width = 4;
            this.vueRoot.size.height = 4;
            this.vueRoot.direction = "right";
            setTimeout(() => {
                if ( callback ) callback();
            }, 500);
            return JSON.stringify(this.vueRoot.coords);
        }

        step(action) {
            let _oldCoords = JSON.stringify(this.vueRoot.coords);
            let coords = this._go(action);
            let _newCoords = JSON.stringify(coords);
            let reward = 0;
            let done = false; 
            if ( this._inCoords(this.vueRoot.targets, coords) ) {
                reward = 1;
                done = true;
                this.vueRoot.showTip("原来是这条路呀。");
                setTimeout(() => {
                    this.vueRoot.hideTip();
                }, 500);
            } else if ( this._inCoords(this.vueRoot.obstacles, coords) ) {
                reward = -1;
                done = true;
                this.vueRoot.showTip("唉，又碰壁了，重新来。");
                setTimeout(() => {
                    this.vueRoot.hideTip();
                }, 500);
            } else {
                reward = 0;
                done = false;
            }
            return {
                observation: JSON.stringify(coords),
                reward: reward,
                done: done
            }
        }

        _inCoords(coordsArr, targetCoord) {
            let isExist = false;
            coordsArr.forEach(element => {
                if ( element.x === targetCoord.x && element.y === targetCoord.y ) {
                    isExist = true;
                    //console.log(coordsArr, targetCoord);
                }
            });
            return isExist;
        }

        _equalCoords(coordsA, coordsB) {
            if ( coordsA.x === coordsB.x && coordsA.y === coordsB.y ) {
                return true;
            } else {
                return false;
            }
        }
    }

    window.Env = Env;
}